package cn.lizemin.builder.origin;

import com.sun.deploy.util.StringUtils;

import java.util.Objects;

/**
 * @author lzm
 * @version 1.0
 * @description: 资源池的配置类的设计，要求满足以下需求
 * 需求：
 *   资源名称（name): 必填
 *   最大总资源数量（）：非必填，默认值：8
 *   最大空闲资源数量：非必填，默认值：8
 *   最小空闲资源数量：非必填，默认值：0
 * @date 2022/4/28 10:28
 */
public class ResourcePoolConfig {

    /**
     * 定义默认值常量,提升程序可读性，对数据进行解释
     */
    private static final int DEFAULT_MAX_TOTAL = 8;
    private static final int DEFAULT_MAX_IDLE = 8;
    private static final int DEFAULT_MIN_IDLE = 0;

    /**资源名称*/
    private String name ;

    /**
     * 对属性设置默认值
     */
    private int maxTotal = DEFAULT_MAX_TOTAL;
    private int maxIdle = DEFAULT_MAX_IDLE;
    private int minIdle = DEFAULT_MIN_IDLE;



    /**
     * 使用构造器对参数进行校验
     *  存在的缺陷：如果参数的个数很多，有8个，9个，构造函数的参数列表会变得很长
     *  那么这样在创建对象的时候，就很容易搞错顺序，传递错误的参数值
     *
     */
//    public ResourcePoolConfig(String name, Integer maxTotal, Integer maxIdle, Integer minIdle) {
//        // 对参数进行校验，而且遵循fail fast的原则，尽量把错误放在前面
//        if (name == null || name == "") {
//            throw new IllegalArgumentException("资源名称为必填项！");
//        }
//        this.name = name;
//
//        /**
//         * int 类型的maxTotal不能和null做比较，所以这里的参数类型为integer类型
//         */
//        if (maxTotal != null) {
//            /**
//             * 我的最初写法，可读性其实还更高写，只是代码量增加了
//             */
////            if (maxTotal >= 0) {
////                this.maxTotal = maxTotal;
////            }else {
////                throw new IllegalArgumentException("最大总资源数量必须大于0");
////            }
//
//            /**
//             * 和上面的代码功能一样，只是更加间接写，提前写异常条件，可以
//             * 让代码更加简洁，少写了很多else代码， 同时也减少了if的多重嵌套
//             *
//             * 即if(){
//             *     else{
//             *         if(){
//             *             else{
//             *                 if(){
//             *                     else{
//             *                         通过重重异常校验，修成正果，但是这显然没有
//             *                         下面的代码的可读性高
//             *                     }
//             *                 }
//             *             }
//             *         }
//             *
//             *     }
//             * }
//             *
//             * 即排除了所有的异常，剩下的就是对的了
//             */
//            if (maxTotal < 0) {//尽量反着写，要是我来写的话，我可能会使用maxTotal < 0
//                throw new IllegalArgumentException("最大总资源数量必须大于0");
//            }
//            this.maxTotal = maxTotal;
//        }
//
//        if (maxIdle != null) {
//            if (maxIdle < 0) {
//                throw new IllegalArgumentException("最大空闲资源数量必须大于0");
//            }
//            this.maxIdle = maxIdle;
//        }
//
//        if (minIdle != null) {
//            if (minIdle < 0) {
//                throw new IllegalArgumentException("最小空闲资源数量必须大于0");
//            }
//            this.minIdle = minIdle;
//        }
//
//
//
//    }

    /**
     * 使用set方法进行参数校验来替代构造函数中可能过长的参数列表
     * 提升程序可读性
     *
     * 存在的缺陷：
     *      set方法不能够实现让参数必填的功能
     *      set方法不能解决参数之间的依赖的校验，比如最小空闲资源数必须小于最大空闲资源数量
     *
     *      setMaxIdle(int max){
     *          //max = 3
     *          this.maxIdle = max;
     *      }
     *
     *      setMinIdle(int min){
     *          min < this.maxIdle;
     *      }
     *      问题在于：两个set方法在使用时的顺序是难以保证的！这会导致参数校验失效
     *
     *      解决参数列表过长，以及参数校验发生依赖的问题，
     *          通过建造者模式！
     * @param name
     */
    public void setName(String name) {
        // 对参数进行校验，而且遵循fail fast的原则，尽量把错误放在前面
        if (name == null || name.equals("")) {
            throw new IllegalArgumentException("资源名称为必填项！");
        }
        this.name = name;
    }

    public void setMaxTotal(int maxTotal) {
        if (maxTotal < 0) {//尽量反着写，要是我来写的话，我可能会使用maxTotal < 0
            throw new IllegalArgumentException("最大总资源数量必须大于0");
        }
        this.maxTotal = maxTotal;
    }

    public void setMaxIdle(int maxIdle) {
        if (maxIdle < 0) {
            throw new IllegalArgumentException("最大空闲资源数量必须大于0");
        }
        this.maxIdle = maxIdle;
    }

    public void setMinIdle(int minIdle) {
        if (minIdle < 0) {
            throw new IllegalArgumentException("最小空闲资源数量必须大于0");
        }
        this.minIdle = minIdle;
    }

    public String getName() {
        return name;
    }

    public int getMaxTotal() {
        return maxTotal;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public int getMinIdle() {
        return minIdle;
    }
}
